package com.feature.core.webmvc;

import java.text.ParseException;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;

import com.feature.core.constant.Constants;
import com.feature.core.constant.DatePatternConstants;
import com.feature.core.domain.Response;
import com.feature.core.exception.ServiceException;

@ControllerAdvice
public class GlobalControllerAdviceHandle {
	private Logger logger = LoggerFactory.getLogger(getClass());

	@ResponseBody
	@ExceptionHandler(Exception.class)
	public Object handleException(Exception ex) {
		ObjectError objectError = null;
		String code = Constants.FAIL;
		String message = Constants.FAIL;
		if (ex instanceof BindException bex) {
			objectError = bex.getBindingResult().getAllErrors().get(0);
		} else if (ex instanceof MethodArgumentNotValidException mex) {
			objectError = mex.getBindingResult().getAllErrors().get(0);
		} else if (ex instanceof ServiceException sex) {
			code = sex.getCode();
			message = sex.getMessage();
		} else {
			logger.error("", ex);
			message = "系统异常，紧急修复中";
		}
		if (objectError != null) {
			message = objectError.getDefaultMessage();
			int index = -1;
			if ((index = message.indexOf(Constants.ERROR_CODE_MESSAGE_SPLIT)) > -1) {
				code = message.substring(0, index);
				message = message.substring(index + 1);
			}else{
			   Object[] args= objectError.getArguments();
			   if(args!=null&&args.length>0&&args[0] instanceof DefaultMessageSourceResolvable resolvable) {
			       message= resolvable.getDefaultMessage()+message;
			   }
			}
		}
		return Response.fail(code, message);
	}

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, new java.beans.PropertyEditorSupport() {
			@Override
			public void setAsText(String text) throws IllegalArgumentException {
				if (StringUtils.isNotBlank(text)) {
					try {
						setValue(DateUtils.parseDate(text, DatePatternConstants.DATE_TIME, DatePatternConstants.DATE));
					} catch (ParseException e) {
						throw new RuntimeException(e);
					}
				} else {
					setValue(null);
				}
			}

			@Override
			public String getAsText() {
				Date value = (Date) getValue();
				return value != null ? DateFormatUtils.format(value, DatePatternConstants.DATE_TIME) : null;
			}
		});
	}

}
